﻿using HDSmartCommunity.DAL;
using HDSmartCommunity.Models;
using MQTTnet;
using MQTTnet.Client;
using MQTTnet.Client.Disconnecting;
using MQTTnet.Client.Options;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace HDSmartCommunity.BUS.MqttBUS
{
    public class PZMqttClient
    {
        IMqttClient _mqttClient;
        MqttClientOptions _options;
        public string SubscribeTopic = "";
        MqttInfo mqttInfo;
        public PZMqttClient()
        {
            MqttDAL mqttDAL = new MqttDAL();
             mqttInfo = mqttDAL.GetMqttInfo();
            SubscribeTopic = "pztest";
            Init();
        }

        public IMqttClient MqttClient { get { return _mqttClient; } }

        public MqttClientOptions Options { get { return _options; } }

        private void Init()
        {
            _mqttClient = new MqttFactory().CreateMqttClient();

            _mqttClient.UseApplicationMessageReceivedHandler(c =>
            {
            });
            _mqttClient.DisconnectedHandler = new MqttClientDisconnectedHandlerDelegate(e =>
            {
                StartConnect();
            });
            _options = new MqttClientOptions()
            {
                ClientId = Guid.NewGuid().ToString().Substring(0, 13)
            };
            _options.ChannelOptions = new MqttClientTcpOptions()
            {
                Server = mqttInfo.mqtt_server,
                Port = mqttInfo.mqtt_port,
            };
            string strName = mqttInfo.mqtt_uname;
            if (!string.IsNullOrEmpty(strName))
            {
                _options.Credentials = new MqttClientCredentials()
                {
                    Username = strName,
                    Password = System.Text.Encoding.Default.GetBytes(mqttInfo.mqtt_pwd)
                };
            }
            _options.CleanSession = true;
            _options.KeepAlivePeriod = TimeSpan.FromSeconds(60);
            StartConnect();
        }

        public void StartConnect()
        {
            Task t = Task.Factory.StartNew(async () =>
            {
                while (true)
                {
                    if (!_mqttClient.IsConnected)
                    {
                        await _mqttClient.ConnectAsync(_options);
                        await _mqttClient.SubscribeAsync(SubscribeTopic, MQTTnet.Protocol.MqttQualityOfServiceLevel.AtMostOnce);
                    }
                    else break;
                    Task.Delay(3000).Wait();
                }
            });
        }
    }
}
